package com.hospital.workstation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ObjectUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.hospital.common.core.domain.R;
import com.hospital.common.core.domain.entity.SysDictData;
import com.hospital.common.core.domain.model.LoginUser;
import com.hospital.common.exception.ServiceException;
import com.hospital.common.helper.LoginHelper;
import com.hospital.common.utils.BeanCopyUtils;
import com.hospital.common.utils.StringUtils;
import com.hospital.common.core.page.TableDataInfo;
import com.hospital.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hospital.system.mapper.SysDictDataMapper;
import com.hospital.workstation.constant.DictConstants;
import com.hospital.workstation.domain.*;
import com.hospital.workstation.domain.bo.ElectronicBadRecordInfoBo;
import com.hospital.workstation.domain.vo.ElectronicBadRecordInfoVo;
import com.hospital.workstation.domain.vo.ElectronicManagerInfoVo;
import com.hospital.workstation.mapper.ElectronicBadRecordInfoMapper;
import com.hospital.workstation.mapper.ElectronicManagerInfoMapper;
import com.hospital.workstation.mapper.PatientBaseInfoMapper;
import com.hospital.workstation.utils.PdfUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import com.hospital.workstation.domain.bo.ElectronicMonitorTwoInfoBo;
import com.hospital.workstation.domain.vo.ElectronicMonitorTwoInfoVo;
import com.hospital.workstation.mapper.ElectronicMonitorTwoInfoMapper;
import com.hospital.workstation.service.IElectronicMonitorTwoInfoService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * B表 药品不良反应/事件报告表Service业务层处理
 *
 * @author hospital
 * @date 2024-05-07
 */
@RequiredArgsConstructor
@Service
public class ElectronicMonitorTwoInfoServiceImpl implements IElectronicMonitorTwoInfoService {

    private final ElectronicMonitorTwoInfoMapper baseMapper;
    private final PatientBaseInfoMapper patientBaseInfoMapper;
    private final ElectronicManagerInfoMapper managerInfoMapper;
    private final ElectronicBadRecordInfoMapper badRecordInfoMapper;
    private final SysDictDataMapper sysDictDataMapper;

    /**
     * 查询B表 药品不良反应/事件报告表
     */
    @Override
    public ElectronicMonitorTwoInfoVo queryById(Long id) {
        ElectronicMonitorTwoInfoVo electronicMonitorTwoInfoVo = baseMapper.selectVoById(id);
        ElectronicManagerInfo electronicManagerInfo = managerInfoMapper.selectOne(new LambdaQueryWrapper<ElectronicManagerInfo>()
            .eq(ElectronicManagerInfo::getMonitorId, electronicMonitorTwoInfoVo.getId()));
        electronicMonitorTwoInfoVo.setMedicalRecordNo(electronicManagerInfo.getMedicalRecordNo());
        electronicMonitorTwoInfoVo.setManageId(electronicManagerInfo.getId());
        // 不良反应/事件记录表
        List<ElectronicBadRecordInfoVo> badRecordInfoVoList = badRecordInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicBadRecordInfo>()
            .eq(ElectronicBadRecordInfo::getMonitorId, id));
        electronicMonitorTwoInfoVo.setElectronicBadRecordInfoVoList(badRecordInfoVoList);
        return electronicMonitorTwoInfoVo;
    }

    /**
     * 查询B表 药品不良反应/事件报告表列表
     */
    @Override
    public TableDataInfo<ElectronicMonitorTwoInfoVo> queryPageList(ElectronicMonitorTwoInfoBo bo, PageQuery pageQuery) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (ObjectUtil.isNull(loginUser)) {
            throw new ServiceException("请先登录!");
        }
        LambdaQueryWrapper<ElectronicMonitorTwoInfo> lqw = buildQueryWrapper(bo);
        Set<String> rolePermission = loginUser.getRolePermission();
        if (rolePermission.contains("monitor")) {
            lqw.eq(ElectronicMonitorTwoInfo::getCreateBy, loginUser.getUsername());
        } else if (rolePermission.contains("quality2")) {
            lqw.eq(ElectronicMonitorTwoInfo::getSubmitStatus, "1");
        } else {
        }
        lqw.orderByDesc(ElectronicMonitorTwoInfo::getMonitorRecordNo)
            .orderByAsc(ElectronicMonitorTwoInfo::getSubmitStatus)
            .orderByDesc(ElectronicMonitorTwoInfo::getCreateTime)
            .select(ElectronicMonitorTwoInfo::getId, ElectronicMonitorTwoInfo::getMonitorRecordNo, ElectronicMonitorTwoInfo::getPhoneNo,
                ElectronicMonitorTwoInfo::getPatientNameAcronym, ElectronicMonitorTwoInfo::getInputFormDate, ElectronicMonitorTwoInfo::getAuditStatus, ElectronicMonitorTwoInfo::getSubmitStatus,
                ElectronicMonitorTwoInfo::getInspectorSign, ElectronicMonitorTwoInfo::getQualityControllerSign);
        Page<ElectronicMonitorTwoInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询B表 药品不良反应/事件报告表列表
     */
    @Override
    public List<ElectronicMonitorTwoInfoVo> queryList(ElectronicMonitorTwoInfoBo bo) {
        LambdaQueryWrapper<ElectronicMonitorTwoInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ElectronicMonitorTwoInfo> buildQueryWrapper(ElectronicMonitorTwoInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ElectronicMonitorTwoInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getMonitorRecordNo() != null, ElectronicMonitorTwoInfo::getMonitorRecordNo, bo.getMonitorRecordNo());
        lqw.eq(StringUtils.isNotBlank(bo.getHospitalNo()), ElectronicMonitorTwoInfo::getHospitalNo, bo.getHospitalNo());
        lqw.eq(bo.getDeptId() != null, ElectronicMonitorTwoInfo::getDeptId, bo.getDeptId());
        lqw.eq(StringUtils.isNotBlank(bo.getBedNo()), ElectronicMonitorTwoInfo::getBedNo, bo.getBedNo());
        lqw.like(StringUtils.isNotBlank(bo.getPatientName()), ElectronicMonitorTwoInfo::getPatientName, bo.getPatientName());
        lqw.like(StringUtils.isNotBlank(bo.getPatientNameAcronym()), ElectronicMonitorTwoInfo::getPatientNameAcronym, bo.getPatientNameAcronym());
        lqw.eq(StringUtils.isNotBlank(bo.getPatientNo()), ElectronicMonitorTwoInfo::getPatientNo, bo.getPatientNo());
        lqw.between(params.get("beginTime") != null && params.get("endTime") != null, ElectronicMonitorTwoInfo::getInputFormDate,
            params.get("beginTime") + " 00:00:00", params.get("endTime") + " 23:59:59");
        lqw.eq(StringUtils.isNotBlank(bo.getBadType()), ElectronicMonitorTwoInfo::getBadType, bo.getBadType());
        lqw.eq(bo.getReportDate() != null, ElectronicMonitorTwoInfo::getReportDate, bo.getReportDate());
        lqw.eq(StringUtils.isNotBlank(bo.getPatientSex()), ElectronicMonitorTwoInfo::getPatientSex, bo.getPatientSex());
        lqw.eq(bo.getBirthdate() != null, ElectronicMonitorTwoInfo::getBirthdate, bo.getBirthdate());
        lqw.eq(StringUtils.isNotBlank(bo.getNation()), ElectronicMonitorTwoInfo::getNation, bo.getNation());
        lqw.eq(StringUtils.isNotBlank(bo.getPhoneNo()), ElectronicMonitorTwoInfo::getPhoneNo, bo.getPhoneNo());
        lqw.eq(StringUtils.isNotBlank(bo.getOriginalIllness()), ElectronicMonitorTwoInfo::getOriginalIllness, bo.getOriginalIllness());
        lqw.eq(StringUtils.isNotBlank(bo.getPillsBadBefore()), ElectronicMonitorTwoInfo::getPillsBadBefore, bo.getPillsBadBefore());
        lqw.like(StringUtils.isNotBlank(bo.getPillsBadBeforeName()), ElectronicMonitorTwoInfo::getPillsBadBeforeName, bo.getPillsBadBeforeName());
        lqw.eq(StringUtils.isNotBlank(bo.getPillsBadFamily()), ElectronicMonitorTwoInfo::getPillsBadFamily, bo.getPillsBadFamily());
        lqw.like(StringUtils.isNotBlank(bo.getPillsBadFamilyName()), ElectronicMonitorTwoInfo::getPillsBadFamilyName, bo.getPillsBadFamilyName());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationFamily()), ElectronicMonitorTwoInfo::getRelationFamily, bo.getRelationFamily());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationFamilyOther()), ElectronicMonitorTwoInfo::getRelationFamilyOther, bo.getRelationFamilyOther());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationInfo()), ElectronicMonitorTwoInfo::getRelationInfo, bo.getRelationInfo());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationInfoOther()), ElectronicMonitorTwoInfo::getRelationInfoOther, bo.getRelationInfoOther());
        lqw.like(StringUtils.isNotBlank(bo.getBadName()), ElectronicMonitorTwoInfo::getBadName, bo.getBadName());
        lqw.eq(StringUtils.isNotBlank(bo.getBadNameOther()), ElectronicMonitorTwoInfo::getBadNameOther, bo.getBadNameOther());
        lqw.eq(bo.getBadTime() != null, ElectronicMonitorTwoInfo::getBadTime, bo.getBadTime());
        lqw.eq(bo.getUseHours() != null, ElectronicMonitorTwoInfo::getUseHours, bo.getUseHours());
        lqw.eq(bo.getUseMinute() != null, ElectronicMonitorTwoInfo::getUseMinute, bo.getUseMinute());
        lqw.eq(bo.getUseDays() != null, ElectronicMonitorTwoInfo::getUseDays, bo.getUseDays());
        lqw.eq(StringUtils.isNotBlank(bo.getIsTrack()), ElectronicMonitorTwoInfo::getIsTrack, bo.getIsTrack());
        lqw.eq(StringUtils.isNotBlank(bo.getTrackResult()), ElectronicMonitorTwoInfo::getTrackResult, bo.getTrackResult());
        lqw.eq(bo.getTurnoverDate() != null, ElectronicMonitorTwoInfo::getTurnoverDate, bo.getTurnoverDate());
        lqw.eq(bo.getTurnoverDays() != null, ElectronicMonitorTwoInfo::getTurnoverDays, bo.getTurnoverDays());
        lqw.eq(StringUtils.isNotBlank(bo.getBadShow()), ElectronicMonitorTwoInfo::getBadShow, bo.getBadShow());
        lqw.eq(StringUtils.isNotBlank(bo.getBadShowOther()), ElectronicMonitorTwoInfo::getBadShowOther, bo.getBadShowOther());
        lqw.eq(StringUtils.isNotBlank(bo.getClinicalExamination()), ElectronicMonitorTwoInfo::getClinicalExamination, bo.getClinicalExamination());
        lqw.eq(StringUtils.isNotBlank(bo.getDispose()), ElectronicMonitorTwoInfo::getDispose, bo.getDispose());
        lqw.eq(StringUtils.isNotBlank(bo.getDisposeOther()), ElectronicMonitorTwoInfo::getDisposeOther, bo.getDisposeOther());
        lqw.eq(StringUtils.isNotBlank(bo.getIsPillsDispose()), ElectronicMonitorTwoInfo::getIsPillsDispose, bo.getIsPillsDispose());
        lqw.eq(StringUtils.isNotBlank(bo.getPillsDispose()), ElectronicMonitorTwoInfo::getPillsDispose, bo.getPillsDispose());
        lqw.eq(StringUtils.isNotBlank(bo.getPillsDisposeOther()), ElectronicMonitorTwoInfo::getPillsDisposeOther, bo.getPillsDisposeOther());
        lqw.eq(StringUtils.isNotBlank(bo.getUseType()), ElectronicMonitorTwoInfo::getUseType, bo.getUseType());
        lqw.eq(StringUtils.isNotBlank(bo.getUseTypeOther()), ElectronicMonitorTwoInfo::getUseTypeOther, bo.getUseTypeOther());
        lqw.eq(StringUtils.isNotBlank(bo.getPillsAmount()), ElectronicMonitorTwoInfo::getPillsAmount, bo.getPillsAmount());
        lqw.eq(StringUtils.isNotBlank(bo.getMenstruumAmount()), ElectronicMonitorTwoInfo::getMenstruumAmount, bo.getMenstruumAmount());
        lqw.eq(StringUtils.isNotBlank(bo.getMenstruumType()), ElectronicMonitorTwoInfo::getMenstruumType, bo.getMenstruumType());
        lqw.eq(StringUtils.isNotBlank(bo.getMenstruumTypeOther()), ElectronicMonitorTwoInfo::getMenstruumTypeOther, bo.getMenstruumTypeOther());
        lqw.eq(StringUtils.isNotBlank(bo.getIndoorTemperature()), ElectronicMonitorTwoInfo::getIndoorTemperature, bo.getIndoorTemperature());
        lqw.eq(StringUtils.isNotBlank(bo.getPlaceTime()), ElectronicMonitorTwoInfo::getPlaceTime, bo.getPlaceTime());
        lqw.eq(StringUtils.isNotBlank(bo.getDrippingSpeed()), ElectronicMonitorTwoInfo::getDrippingSpeed, bo.getDrippingSpeed());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCompoundUse()), ElectronicMonitorTwoInfo::getIsCompoundUse, bo.getIsCompoundUse());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCompoundUsePills()), ElectronicMonitorTwoInfo::getIsCompoundUsePills, bo.getIsCompoundUsePills());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCountineUseBefore()), ElectronicMonitorTwoInfo::getIsCountineUseBefore, bo.getIsCountineUseBefore());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCountineUseBeforeInjection()), ElectronicMonitorTwoInfo::getIsCountineUseBeforeInjection, bo.getIsCountineUseBeforeInjection());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCountineUseAfter()), ElectronicMonitorTwoInfo::getIsCountineUseAfter, bo.getIsCountineUseAfter());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCountineUseAfterInjection()), ElectronicMonitorTwoInfo::getIsCountineUseAfterInjection, bo.getIsCountineUseAfterInjection());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCountineUseUnderway()), ElectronicMonitorTwoInfo::getIsCountineUseUnderway, bo.getIsCountineUseUnderway());
        lqw.eq(StringUtils.isNotBlank(bo.getIsCountineUseUnderwayInjection()), ElectronicMonitorTwoInfo::getIsCountineUseUnderwayInjection, bo.getIsCountineUseUnderwayInjection());
        lqw.eq(StringUtils.isNotBlank(bo.getInjectionBefore()), ElectronicMonitorTwoInfo::getInjectionBefore, bo.getInjectionBefore());
        lqw.eq(StringUtils.isNotBlank(bo.getInjectionAfter()), ElectronicMonitorTwoInfo::getInjectionAfter, bo.getInjectionAfter());
        lqw.eq(StringUtils.isNotBlank(bo.getInjectionMeasure()), ElectronicMonitorTwoInfo::getInjectionMeasure, bo.getInjectionMeasure());
        lqw.eq(StringUtils.isNotBlank(bo.getIsInjectionEat()), ElectronicMonitorTwoInfo::getIsInjectionEat, bo.getIsInjectionEat());
        lqw.eq(StringUtils.isNotBlank(bo.getIsSeafood()), ElectronicMonitorTwoInfo::getIsSeafood, bo.getIsSeafood());
        lqw.eq(StringUtils.isNotBlank(bo.getIsEgg()), ElectronicMonitorTwoInfo::getIsEgg, bo.getIsEgg());
        lqw.eq(StringUtils.isNotBlank(bo.getIsDust()), ElectronicMonitorTwoInfo::getIsDust, bo.getIsDust());
        lqw.eq(StringUtils.isNotBlank(bo.getIsAlcohol()), ElectronicMonitorTwoInfo::getIsAlcohol, bo.getIsAlcohol());
        lqw.eq(StringUtils.isNotBlank(bo.getFoodOther()), ElectronicMonitorTwoInfo::getFoodOther, bo.getFoodOther());
        lqw.eq(StringUtils.isNotBlank(bo.getIsTakePills()), ElectronicMonitorTwoInfo::getIsTakePills, bo.getIsTakePills());
        lqw.like(StringUtils.isNotBlank(bo.getTakePillsName()), ElectronicMonitorTwoInfo::getTakePillsName, bo.getTakePillsName());
        lqw.eq(StringUtils.isNotBlank(bo.getBadResult()), ElectronicMonitorTwoInfo::getBadResult, bo.getBadResult());
        lqw.eq(StringUtils.isNotBlank(bo.getSequelaeManifestation()), ElectronicMonitorTwoInfo::getSequelaeManifestation, bo.getSequelaeManifestation());
        lqw.eq(StringUtils.isNotBlank(bo.getDieReason()), ElectronicMonitorTwoInfo::getDieReason, bo.getDieReason());
        lqw.eq(bo.getDieDate() != null, ElectronicMonitorTwoInfo::getDieDate, bo.getDieDate());
        lqw.eq(StringUtils.isNotBlank(bo.getDisappearedOrRelieve()), ElectronicMonitorTwoInfo::getDisappearedOrRelieve, bo.getDisappearedOrRelieve());
        lqw.eq(StringUtils.isNotBlank(bo.getAgainShow()), ElectronicMonitorTwoInfo::getAgainShow, bo.getAgainShow());
        lqw.eq(StringUtils.isNotBlank(bo.getToOriginalAffect()), ElectronicMonitorTwoInfo::getToOriginalAffect, bo.getToOriginalAffect());
        lqw.eq(StringUtils.isNotBlank(bo.getSequela()), ElectronicMonitorTwoInfo::getSequela, bo.getSequela());
        lqw.eq(bo.getHappenTime() != null, ElectronicMonitorTwoInfo::getHappenTime, bo.getHappenTime());
        lqw.eq(StringUtils.isNotBlank(bo.getUseMedicine()), ElectronicMonitorTwoInfo::getUseMedicine, bo.getUseMedicine());
        lqw.eq(bo.getUseTime() != null, ElectronicMonitorTwoInfo::getUseTime, bo.getUseTime());
        lqw.eq(StringUtils.isNotBlank(bo.getDevelopSymptoms()), ElectronicMonitorTwoInfo::getDevelopSymptoms, bo.getDevelopSymptoms());
        lqw.eq(StringUtils.isNotBlank(bo.getCheckSomething()), ElectronicMonitorTwoInfo::getCheckSomething, bo.getCheckSomething());
        lqw.eq(StringUtils.isNotBlank(bo.getCheckValue()), ElectronicMonitorTwoInfo::getCheckValue, bo.getCheckValue());
        lqw.eq(StringUtils.isNotBlank(bo.getDrugWithdrawal()), ElectronicMonitorTwoInfo::getDrugWithdrawal, bo.getDrugWithdrawal());
        lqw.eq(StringUtils.isNotBlank(bo.getOtherMeasures()), ElectronicMonitorTwoInfo::getOtherMeasures, bo.getOtherMeasures());
        lqw.eq(StringUtils.isNotBlank(bo.getDecrement()), ElectronicMonitorTwoInfo::getDecrement, bo.getDecrement());
        lqw.eq(StringUtils.isNotBlank(bo.getDecrementOtherMeasures()), ElectronicMonitorTwoInfo::getDecrementOtherMeasures, bo.getDecrementOtherMeasures());
        lqw.eq(StringUtils.isNotBlank(bo.getDrugOn()), ElectronicMonitorTwoInfo::getDrugOn, bo.getDrugOn());
        lqw.eq(StringUtils.isNotBlank(bo.getNoOtherMeasures()), ElectronicMonitorTwoInfo::getNoOtherMeasures, bo.getNoOtherMeasures());
        lqw.eq(StringUtils.isNotBlank(bo.getReuse()), ElectronicMonitorTwoInfo::getReuse, bo.getReuse());
        lqw.eq(bo.getReuseUseTime() != null, ElectronicMonitorTwoInfo::getReuseUseTime, bo.getReuseUseTime());
        lqw.eq(StringUtils.isNotBlank(bo.getReuseUseMedicine()), ElectronicMonitorTwoInfo::getReuseUseMedicine, bo.getReuseUseMedicine());
        lqw.eq(bo.getReuseDuration() != null, ElectronicMonitorTwoInfo::getReuseDuration, bo.getReuseDuration());
        lqw.eq(StringUtils.isNotBlank(bo.getReuseDevelopSymptoms()), ElectronicMonitorTwoInfo::getReuseDevelopSymptoms, bo.getReuseDevelopSymptoms());
        lqw.eq(StringUtils.isNotBlank(bo.getReuseHandle()), ElectronicMonitorTwoInfo::getReuseHandle, bo.getReuseHandle());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationReportPerson()), ElectronicMonitorTwoInfo::getRelationReportPerson, bo.getRelationReportPerson());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationInspectorSign()), ElectronicMonitorTwoInfo::getRelationInspectorSign, bo.getRelationInspectorSign());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationReportDept()), ElectronicMonitorTwoInfo::getRelationReportDept, bo.getRelationReportDept());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationQualityControllerSign()), ElectronicMonitorTwoInfo::getRelationQualityControllerSign, bo.getRelationQualityControllerSign());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationTime()), ElectronicMonitorTwoInfo::getRelationTime, bo.getRelationTime());
        lqw.eq(StringUtils.isNotBlank(bo.getAccordWithBadType()), ElectronicMonitorTwoInfo::getAccordWithBadType, bo.getAccordWithBadType());
        lqw.eq(StringUtils.isNotBlank(bo.getIsDisappearedOrRelieve()), ElectronicMonitorTwoInfo::getIsDisappearedOrRelieve, bo.getIsDisappearedOrRelieve());
        lqw.eq(StringUtils.isNotBlank(bo.getIsAgainShow()), ElectronicMonitorTwoInfo::getIsAgainShow, bo.getIsAgainShow());
        lqw.eq(StringUtils.isNotBlank(bo.getIsEffectOther()), ElectronicMonitorTwoInfo::getIsEffectOther, bo.getIsEffectOther());
        lqw.eq(StringUtils.isNotBlank(bo.getSeverityBadShow()), ElectronicMonitorTwoInfo::getSeverityBadShow, bo.getSeverityBadShow());
        lqw.likeRight(StringUtils.isNotBlank(bo.getInspectorSign()), ElectronicMonitorTwoInfo::getInspectorSign, bo.getInspectorSign());
        lqw.eq(bo.getInspectorDate() != null, ElectronicMonitorTwoInfo::getInspectorDate, bo.getInspectorDate());
        lqw.likeRight(StringUtils.isNotBlank(bo.getQualityControllerSign()), ElectronicMonitorTwoInfo::getQualityControllerSign, bo.getQualityControllerSign());
        lqw.eq(bo.getQualityControllerSignDate() != null, ElectronicMonitorTwoInfo::getQualityControllerSignDate, bo.getQualityControllerSignDate());
        lqw.eq(StringUtils.isNotBlank(bo.getSubmitStatus()), ElectronicMonitorTwoInfo::getSubmitStatus, bo.getSubmitStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getAuditStatus()), ElectronicMonitorTwoInfo::getAuditStatus, bo.getAuditStatus());
        return lqw;
    }

    /**
     * 新增B表 药品不良反应/事件报告表
     */
    @Transactional
    @Override
    public R<Void> insertByBo(ElectronicMonitorTwoInfoBo bo) {
        // 1.保存B表信息
        ElectronicMonitorTwoInfo electronicMonitorTwoInfo = BeanUtil.toBean(bo, ElectronicMonitorTwoInfo.class);
        validEntityBeforeSave(electronicMonitorTwoInfo);
        boolean flag = baseMapper.insertOrUpdate(electronicMonitorTwoInfo);
        if (!flag) {
            throw new ServiceException("保存B表信息异常");
        }
        // 2.保存不良反应/事件记录表
        try {
            badRecordInfoMapper.delete(new LambdaQueryWrapper<ElectronicBadRecordInfo>()
                .eq(ElectronicBadRecordInfo::getMonitorId, electronicMonitorTwoInfo.getId()));
        } catch (Exception e) {
            throw new ServiceException("删除不良反应/事件记录异常");
        }
        List<ElectronicBadRecordInfoBo> electronicBadRecordInfoBoList = bo.getElectronicBadRecordInfoBoList();
        if (ObjectUtil.isNotNull(electronicBadRecordInfoBoList) && electronicBadRecordInfoBoList.size() > 0) {
            List<ElectronicBadRecordInfo> electronicBadRecordInfoList = BeanCopyUtils.copyList(electronicBadRecordInfoBoList, ElectronicBadRecordInfo.class);
            electronicBadRecordInfoList.stream().forEach(electronicBadRecordInfo -> electronicBadRecordInfo.setMonitorId(electronicMonitorTwoInfo.getId()));
            flag = badRecordInfoMapper.insertBatch(electronicBadRecordInfoList);
            if (!flag) {
                throw new ServiceException("保存不良反应/事件记录异常");
            }
        }
        // 3.不良反应/事件记录
        Long manageId = bo.getManageId();
        ElectronicManagerInfo electronicManagerInfo = new ElectronicManagerInfo();
        // 监测管理主键id
        if (ObjectUtil.isNotNull(manageId)) {
            electronicManagerInfo.setId(manageId);
        }
        // 患者流水号
        Integer medicalRecordNo = bo.getMedicalRecordNo();
        if (ObjectUtil.isNull(medicalRecordNo)) {
            throw new ServiceException("患者流水号不能为空");
        }
        electronicManagerInfo.setMedicalRecordNo(medicalRecordNo);
        // 监测表id
        electronicManagerInfo.setMonitorId(electronicMonitorTwoInfo.getId());
        // 监测表流水号
        electronicManagerInfo.setMonitorRecordNo(electronicMonitorTwoInfo.getMonitorRecordNo());
        // 表类型
        electronicManagerInfo.setMonitorTableType(DictConstants.MONITOR_TABLE_TYPE_B);
        // 入组日期
        electronicManagerInfo.setInputFormDate(electronicMonitorTwoInfo.getInputFormDate());
        // 是否已入组（0未入组 1已入组）
        electronicManagerInfo.setIsInputForm(DictConstants.IS_INPUT_FORM_Y);
        flag = managerInfoMapper.insertOrUpdate(electronicManagerInfo);
        if (!flag) {
            throw new ServiceException("新增或更新监测管理信息异常");
        }
        // 4.修改基本患者信息
        PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
            .eq(PatientBaseInfo::getMedicalRecordNo, bo.getMedicalRecordNo()));
        patientBaseInfo.setIsHaveMonitor("1");
        flag = patientBaseInfoMapper.updateById(patientBaseInfo) > 0;
        if (!flag) {
            throw new ServiceException("修改患者信息失败");
        }
        return R.ok("保存成功");
    }

    /**
     * 修改B表 药品不良反应/事件报告表
     */
    @Override
    public Boolean updateByBo(ElectronicMonitorTwoInfoBo bo) {
        ElectronicMonitorTwoInfo update = BeanUtil.toBean(bo, ElectronicMonitorTwoInfo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ElectronicMonitorTwoInfo entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除B表 药品不良反应/事件报告表
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        try {
            // 1.删除管理信息表数据
            managerInfoMapper.delete(new LambdaQueryWrapper<ElectronicManagerInfo>()
                .eq(ElectronicManagerInfo::getMonitorId, ids.toArray()[0])
                .eq(ElectronicManagerInfo::getMonitorTableType, "1"));
            // 2.删除B表数据
            return baseMapper.deleteBatchIds(ids) > 0;
        } catch (Exception e) {
            throw new ServiceException("删除异常");
        }
    }

    /**
     * 根据患者流水号查询B表信息
     *
     * @param medicalRecordNo 患者流水号
     * @return
     */
    @Override
    public R<ElectronicMonitorTwoInfoVo> queryMonitorTwoInfo(Integer medicalRecordNo) {
        ElectronicMonitorTwoInfoVo electronicMonitorTwoInfoVo = new ElectronicMonitorTwoInfoVo();
        // 1.查询患者基本信息
        PatientBaseInfo patientBaseInfo = patientBaseInfoMapper.selectOne(new LambdaQueryWrapper<PatientBaseInfo>()
            .eq(PatientBaseInfo::getMedicalRecordNo, medicalRecordNo));
        if (ObjectUtil.isNull(patientBaseInfo)) {
            throw new ServiceException("患者已不存在");
        } else {
            electronicMonitorTwoInfoVo.setMedicalRecordNo(patientBaseInfo.getMedicalRecordNo());
            // 住院号
            electronicMonitorTwoInfoVo.setPatientNo("AA" + patientBaseInfo.getMedicareNo());
            // 患者姓名缩写
            String acronymName = StringUtils.getChinesePerLetterToUpper(patientBaseInfo.getPatientName());
            electronicMonitorTwoInfoVo.setPatientNameAcronym(StringUtils.retainDefaultLength(4, acronymName, "*"));
            // 患者姓名
            electronicMonitorTwoInfoVo.setPatientName(patientBaseInfo.getPatientName());
            // 性别
            electronicMonitorTwoInfoVo.setPatientSex(patientBaseInfo.getPatientSex());
            // 出生日期
            electronicMonitorTwoInfoVo.setBirthdate(patientBaseInfo.getBirthdate());
            // 民族
            electronicMonitorTwoInfoVo.setNation(patientBaseInfo.getNation());
            // 联系方式
            electronicMonitorTwoInfoVo.setPhoneNo(patientBaseInfo.getPhoneNo());
        }
        // 2.查询未入组的B表信息
        ElectronicManagerInfoVo electronicManagerInfoVo = managerInfoMapper.selectVoOne(new LambdaQueryWrapper<ElectronicManagerInfo>()
            .eq(ElectronicManagerInfo::getMedicalRecordNo, medicalRecordNo)
            .eq(ElectronicManagerInfo::getMonitorTableType, DictConstants.MONITOR_TABLE_TYPE_B)
            .eq(ElectronicManagerInfo::getIsInputForm, DictConstants.IS_INPUT_FORM_N));
        if (ObjectUtil.isNotNull(electronicManagerInfoVo)) {
            electronicMonitorTwoInfoVo.setManageId(electronicManagerInfoVo.getId());
            return R.ok(electronicMonitorTwoInfoVo);
        }
        // 3.查询最近入组的B表信息
        electronicManagerInfoVo = managerInfoMapper.selectVoOne(new LambdaQueryWrapper<ElectronicManagerInfo>()
            .eq(ElectronicManagerInfo::getMedicalRecordNo, medicalRecordNo)
            .eq(ElectronicManagerInfo::getMonitorTableType, DictConstants.MONITOR_TABLE_TYPE_B)
            .eq(ElectronicManagerInfo::getIsInputForm, DictConstants.IS_INPUT_FORM_Y)
            .orderByDesc(ElectronicManagerInfo::getUpdateTime)
            .last("limit 1"));
        if (ObjectUtil.isNotNull(electronicManagerInfoVo)) {
            // 3.1 根据监测表id查询B表信息
            Long monitorId = electronicManagerInfoVo.getMonitorId();
            if (ObjectUtil.isNull(monitorId)) {
                throw new ServiceException("没有查询到监测表id");
            }
            electronicMonitorTwoInfoVo = baseMapper.selectVoById(monitorId);
            electronicMonitorTwoInfoVo.setMedicalRecordNo(patientBaseInfo.getMedicalRecordNo());
            // B表信息已经不存在
            if (ObjectUtil.isNull(electronicManagerInfoVo)) {
                managerInfoMapper.deleteById(electronicManagerInfoVo.getId());
                return R.ok(electronicMonitorTwoInfoVo);
            }
            // 3.2 B表信息存在
            electronicMonitorTwoInfoVo.setManageId(electronicManagerInfoVo.getId());
            // 查询不良反应/事件记录信息
            List<ElectronicBadRecordInfoVo> electronicBadRecordInfoVoList = badRecordInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicBadRecordInfo>()
                .eq(ElectronicBadRecordInfo::getMonitorId, monitorId));
            electronicMonitorTwoInfoVo.setElectronicBadRecordInfoVoList(electronicBadRecordInfoVoList);
            return R.ok(electronicMonitorTwoInfoVo);
        }
        return R.ok(electronicMonitorTwoInfoVo);
    }

    /**
     * 检测表流水号判重
     *
     * @param monitorRecordNo 检测表流水号
     * @return
     */
    @Override
    public R<Boolean> isExistMonitorRecordNo(Integer monitorRecordNo) {
        List<ElectronicMonitorTwoInfoVo> electronicMonitorTwoInfoVoList = baseMapper.selectVoList(new LambdaQueryWrapper<ElectronicMonitorTwoInfo>()
            .eq(ElectronicMonitorTwoInfo::getMonitorRecordNo, monitorRecordNo));
        return electronicMonitorTwoInfoVoList.size() > 0 ? R.ok("已存在", false) : R.ok("不存在", true);
    }

    /**
     * 驳回
     *
     * @param bo
     * @return
     */
    @Override
    public R<Void> reject(ElectronicMonitorTwoInfoBo bo) {
        Long id = bo.getId();
        if (ObjectUtil.isNull(id)) {
            throw new ServiceException("id不能为空");
        }
        ElectronicMonitorTwoInfo electronicMonitorTwoInfo = baseMapper.selectById(id);
        electronicMonitorTwoInfo.setRejectReason(bo.getRejectReason());
        electronicMonitorTwoInfo.setMonitorRecordNo(bo.getMonitorRecordNo());
        electronicMonitorTwoInfo.setSubmitStatus("0");
        electronicMonitorTwoInfo.setAuditStatus("0");
        boolean flag = baseMapper.updateById(electronicMonitorTwoInfo) > 0;
        if (!flag) {
            return R.fail("驳回失败");
        }
        return R.ok("驳回成功");
    }

    /**
     * 导出PDF B表
     *
     * @param response
     * @param ids
     */
    @Override
    public void exportFile(HttpServletResponse response, Long[] ids) throws IOException {
        String zipName = "舒血宁注射液监测表（B）.zip";
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zipOut = new ZipOutputStream(outputStream);
        for (int i = 0; i < ids.length; i++) {
            long id = ids[i];
            ElectronicMonitorTwoInfoVo electronicMonitorTwoInfoVo = baseMapper.selectVoById(id);
            List<ElectronicBadRecordInfoVo> badRecordInfoVoList = badRecordInfoMapper.selectVoList(new LambdaQueryWrapper<ElectronicBadRecordInfo>()
                .eq(ElectronicBadRecordInfo::getMonitorId, electronicMonitorTwoInfoVo.getId()));
            byte[] export = export(electronicMonitorTwoInfoVo, badRecordInfoVoList);
            byte[] bytes = PdfUtil.word2pdf(export);
            String name = "舒血宁注射液监测表（B）_" + electronicMonitorTwoInfoVo.getMonitorRecordNo() + ".pdf";
            ZipEntry entry = new ZipEntry(name); // 设置zip文件中的文件名
            zipOut.putNextEntry(entry);
            zipOut.write(bytes);
            zipOut.closeEntry();
        }
        // 关闭zip输出流
        zipOut.close();
        IOUtils.closeQuietly(zipOut);
        byte[] data = outputStream.toByteArray();
        genCode(response, data, zipName);
    }

    private byte[] export(ElectronicMonitorTwoInfoVo electronicMonitorTwoInfoVo,
                          List<ElectronicBadRecordInfoVo> badRecordInfoVoList) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            Map<String, Object> datas = buildDataMap(electronicMonitorTwoInfoVo, badRecordInfoVoList);

            // 创建循环策略和配置
            LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
            Configure config = Configure.builder()
                .bind("badRecordInfo", policy)
                .build();

            ResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource("classpath:template/B.docx");
            InputStream inputStream = resource.getInputStream();
            XWPFTemplate template = XWPFTemplate.compile(inputStream, config).render(datas);
            template.write(out);
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("导出失败");
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private Map<String, Object> buildDataMap(ElectronicMonitorTwoInfoVo electronicMonitorTwoInfoVo, List<ElectronicBadRecordInfoVo> badRecordInfoVoList) {
        Map<String, Object> datas = new HashMap<>();
        // 流水号
        datas.put("monitorRecordNo", electronicMonitorTwoInfoVo.getMonitorRecordNo());
        // 医院编号
        datas.put("hospitalNo", electronicMonitorTwoInfoVo.getHospitalNo());
        // 患者姓名缩写
        datas.put("patientNameAcronym", electronicMonitorTwoInfoVo.getPatientNameAcronym());
        // 住院号
        datas.put("patientNo", electronicMonitorTwoInfoVo.getPatientNo());
        // 入组日期
        Date inputFormDate = electronicMonitorTwoInfoVo.getInputFormDate();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy /MM /dd");
        if (ObjectUtil.isNotNull(inputFormDate)) {
            datas.put("inputFormDate", dateFormat.format(inputFormDate));
        } else {
            datas.put("inputFormDate", "");
        }
        // 患者姓名
        datas.put("patientName", electronicMonitorTwoInfoVo.getPatientName());
        // 性别
        String patientSex = electronicMonitorTwoInfoVo.getPatientSex();
        Map<String, Object> patientSex1 = getData0("patientSex", patientSex);
        datas.putAll(patientSex1);
        // 出生日期
        dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        Date birthdate = electronicMonitorTwoInfoVo.getBirthdate();
        if (ObjectUtil.isNotNull(birthdate)) {
            datas.put("birthdate", dateFormat.format(birthdate));
        } else {
            datas.put("birthdate", "");
        }
        // 民族
        datas.put("nation", electronicMonitorTwoInfoVo.getNation());
        // 联系方式
        datas.put("phoneNo", electronicMonitorTwoInfoVo.getPhoneNo());
        // 原患疾病
        datas.put("originalIllness", electronicMonitorTwoInfoVo.getOriginalIllness());
        // 既往药品不良反应/事件
        String pillsBadBefore = electronicMonitorTwoInfoVo.getPillsBadBefore();
        Map<String, Object> pillsBadBeforeMap = getData0("pillsBadBefore", pillsBadBefore);
        datas.putAll(pillsBadBeforeMap);
        if (StringUtils.equals(pillsBadBefore, "1")) {
            if (StringUtils.isNotBlank(electronicMonitorTwoInfoVo.getPillsBadBeforeName())) {
                datas.put("pillsBadBeforeName", electronicMonitorTwoInfoVo.getPillsBadBeforeName());
            } else {
                datas.put("pillsBadBeforeName", "");
            }
        }
        // 家族药品不良反应/事件
        String pillsBadFamily = electronicMonitorTwoInfoVo.getPillsBadFamily();
        Map<String, Object> pillsBadFamilyMap = getData0("pillsBadFamily", pillsBadFamily);
        datas.putAll(pillsBadFamilyMap);
        if (StringUtils.equals(pillsBadFamily, "1")) {
            datas.put("pillsBadFamilyName", electronicMonitorTwoInfoVo.getPillsBadFamilyName());
            String relationFamily = electronicMonitorTwoInfoVo.getRelationFamily();
            Map<String, Object> relationFamilyMap = getData0("relationFamily", relationFamily);
            datas.putAll(relationFamilyMap);
            if (StringUtils.equals(relationFamily, "2")) {
                if (StringUtils.isNotBlank(electronicMonitorTwoInfoVo.getRelationFamilyOther())) {
                    datas.put("relationFamilyOther", electronicMonitorTwoInfoVo.getRelationFamilyOther());
                } else {
                    datas.put("relationFamilyOther", "");
                }
            }
        }
        // 相关信息
        String relationInfo = electronicMonitorTwoInfoVo.getRelationInfo();
        Map<String, Object> relationInfoMap = getData1("relationInfo", relationInfo);
        datas.putAll(relationInfoMap);
        if (StringUtils.equals(relationInfo, "7")) {
            if (StringUtils.isNotBlank(electronicMonitorTwoInfoVo.getRelationInfoOther())) {
                datas.put("relationInfoOther", electronicMonitorTwoInfoVo.getRelationInfoOther());
            } else {
                datas.put("relationInfoOther", "");
            }
        }
        // 不良反应/事件名称
        List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("adverse_reaction");
        Map<String, String> sysDictDataMap = sysDictDataList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        String badName = electronicMonitorTwoInfoVo.getBadName();
        if (StringUtils.isNotBlank(badName)) {
            datas.put("badName", sysDictDataMap.get(badName));
        } else {
            datas.put("badName", "");
        }
        // 不良反应/事件发生时间
        Date badTime = electronicMonitorTwoInfoVo.getBadTime();
        if (ObjectUtil.isNotNull(badTime)) {
            datas.put("year1", DateUtil.year(badTime) - 2000);
            datas.put("month1", DateUtil.month(badTime) + 1);
            datas.put("day1", DateUtil.dayOfMonth(badTime));
            datas.put("hour1", DateUtil.hour(badTime, true));
        }
        // 出现不良反应/事件距用药多长时间
        // 小时
        datas.put("useHours", electronicMonitorTwoInfoVo.getUseHours());
        // 分
        datas.put("useMinute", electronicMonitorTwoInfoVo.getUseMinute());
        // 天
        datas.put("useDays", electronicMonitorTwoInfoVo.getUseDays());
        // 出院后是否跟踪回访
        String isTrack = electronicMonitorTwoInfoVo.getIsTrack();
        Map<String, Object> isTrackMap = getData0("isTrack", isTrack);
        datas.putAll(isTrackMap);
        if (StringUtils.equals(isTrack, "1")) {
            if (StringUtils.isNotBlank(electronicMonitorTwoInfoVo.getTrackResult())) {
                datas.put("trackResult", electronicMonitorTwoInfoVo.getTrackResult());
            } else {
                datas.put("trackResult", "");
            }
        }
        // 不良反应/事件转归时间
        Date turnoverDate = electronicMonitorTwoInfoVo.getTurnoverDate();
        if (ObjectUtil.isNotNull(turnoverDate)) {
            datas.put("year2", DateUtil.year(turnoverDate) - 2000);
            datas.put("month2", DateUtil.month(turnoverDate) + 1);
            datas.put("day2", DateUtil.dayOfMonth(turnoverDate));
            datas.put("hour2", DateUtil.hour(turnoverDate, true));
        }
        // 不良反应发生在第几天
        datas.put("turnoverDays", electronicMonitorTwoInfoVo.getTurnoverDays());
        // 表现
        String badShow = electronicMonitorTwoInfoVo.getBadShow();
        List<String> badShowKeyList = Arrays.asList(badShow.split(","));
        List<String> badShowValueList = new ArrayList<>();
        Map<String, String> badShowKeyValueMap = definedBadShow();
        badShowKeyList.stream().forEach(s -> {
            badShowValueList.add(badShowKeyValueMap.get(s));
        });
        Collections.sort(badShowValueList);
        badShow = StringUtils.join(badShowValueList, ",").trim();
        Map<String, Object> badShowMap = getData1("badShow", badShow);
        datas.putAll(badShowMap);
        if (badShow.contains("54")) {
            datas.put("badShowOther", electronicMonitorTwoInfoVo.getBadShowOther());
        }
        // 临床检验（主要异常指标）
        datas.put("clinicalExamination", electronicMonitorTwoInfoVo.getClinicalExamination());
        // 处理
        String dispose = electronicMonitorTwoInfoVo.getDispose();
        Map<String, Object> disposeMap = getData0("dispose", dispose);
        datas.putAll(disposeMap);
        if (StringUtils.equals(dispose, "4")) {
            datas.put("disposeOther", electronicMonitorTwoInfoVo.getDisposeOther());
        }
        // 用药处理
        String isPillsDispose = electronicMonitorTwoInfoVo.getIsPillsDispose();
        Map<String, Object> isPillsDisposeMap = getData0("isPillsDispose", isPillsDispose);
        datas.putAll(isPillsDisposeMap);
        if (StringUtils.equals(isPillsDispose, "1")) {
            String pillsDispose = electronicMonitorTwoInfoVo.getPillsDispose();
            Map<String, Object> pillsDisposeMap = getData1("pillsDispose", pillsDispose);
            datas.putAll(pillsDisposeMap);
            if (StringUtils.equals(pillsDispose, "5")) {
                datas.put("pillsDisposeOther", electronicMonitorTwoInfoVo.getPillsDisposeOther());
            }
        }
        // 使用方式
        String useType = electronicMonitorTwoInfoVo.getUseType();
        Map<String, Object> useTypeMap = getData1("useType", useType);
        datas.putAll(useTypeMap);
        if (StringUtils.equals(useType, "5")) {
            datas.put("useTypeOther", electronicMonitorTwoInfoVo.getUseTypeOther());
        }
        // 药物剂量
        datas.put("pillsAmount", electronicMonitorTwoInfoVo.getPillsAmount());
        // 溶媒用量
        datas.put("menstruumAmount", electronicMonitorTwoInfoVo.getMenstruumAmount());
        // 溶媒
        String menstruumType = electronicMonitorTwoInfoVo.getMenstruumType();
        Map<String, Object> menstruumTypeMap = getData1("menstruumType", menstruumType);
        datas.putAll(menstruumTypeMap);
        if (StringUtils.equals("menstruumType", "4")) {
            datas.put("menstruumTypeOther", electronicMonitorTwoInfoVo.getMenstruumTypeOther());
        }
        // 注射室温
        datas.put("indoorTemperature", electronicMonitorTwoInfoVo.getIndoorTemperature());
        // 配液放置时间
        datas.put("placeTime", electronicMonitorTwoInfoVo.getPlaceTime());
        // 滴速
        datas.put("drippingSpeed", electronicMonitorTwoInfoVo.getDrippingSpeed());
        // 是否与其它药物配制使用
        String isCompoundUse = electronicMonitorTwoInfoVo.getIsCompoundUse();
        Map<String, Object> isCompoundUseMap = getData0("isCompoundUse", isCompoundUse);
        datas.putAll(isCompoundUseMap);
        if (StringUtils.equals(isCompoundUse, "1")) {
            datas.put("isCompoundUsePills", electronicMonitorTwoInfoVo.getIsCompoundUsePills());
        }
        // 注射前  是否连续使用其它注射剂
        String isCountineUseBefore = electronicMonitorTwoInfoVo.getIsCountineUseBefore();
        Map<String, Object> isCountineUseBeforeMap = getData0("isCountineUseBefore", isCountineUseBefore);
        datas.putAll(isCountineUseBeforeMap);
        if (StringUtils.equals(isCountineUseBefore, "1")) {
            datas.put("isCountineUseBeforeInjection", electronicMonitorTwoInfoVo.getIsCountineUseBeforeInjection());
        }
        // 注射后  是否连续使用其它注射剂
        String isCountineUseAfter = electronicMonitorTwoInfoVo.getIsCountineUseAfter();
        Map<String, Object> isCountineUseAfterMap = getData0("isCountineUseAfter", isCountineUseAfter);
        datas.putAll(isCountineUseAfterMap);
        if (StringUtils.equals(isCountineUseAfter, "1")) {
            datas.put("isCountineUseAfterInjection", electronicMonitorTwoInfoVo.getIsCountineUseAfterInjection());
        }
        // 注射期间  是否同时使用其它注射剂（不同通路同时静点）
        String isCountineUseUnderway = electronicMonitorTwoInfoVo.getIsCountineUseUnderway();
        Map<String, Object> isCountineUseUnderwayMap = getData0("isCountineUseUnderway", isCountineUseUnderway);
        datas.putAll(isCountineUseUnderwayMap);
        if (StringUtils.equals(isCountineUseUnderway, "1")) {
            datas.put("isCountineUseUnderwayInjection", electronicMonitorTwoInfoVo.getIsCountineUseUnderwayInjection());
        }
        // 注射前
        String injectionBefore = electronicMonitorTwoInfoVo.getInjectionBefore();
        Map<String, Object> injectionBeforeMap = getData0("injectionBefore", injectionBefore);
        datas.putAll(injectionBeforeMap);
        // 注射后
        String injectionAfter = electronicMonitorTwoInfoVo.getInjectionAfter();
        Map<String, Object> injectionAfterMap = getData0("injectionAfter", injectionAfter);
        datas.putAll(injectionAfterMap);
        // 注射期间注射部位辅助治疗措施
        String injectionMeasure = electronicMonitorTwoInfoVo.getInjectionMeasure();
        Map<String, Object> injectionMeasureMap = getData0("injectionMeasure", injectionMeasure);
        datas.putAll(injectionMeasureMap);
        // 注射期间是否进食
        String isInjectionEat = electronicMonitorTwoInfoVo.getIsInjectionEat();
        Map<String, Object> isInjectionEatMap = getData0("isInjectionEat", isInjectionEat);
        datas.putAll(isInjectionEatMap);
        // 食物或成份
        // 海鲜
        String isSeafood = electronicMonitorTwoInfoVo.getIsSeafood();
        Map<String, Object> isSeafoodMap = getData0("isSeafood", isSeafood);
        datas.putAll(isSeafoodMap);
        // 鸡蛋
        String isEgg = electronicMonitorTwoInfoVo.getIsEgg();
        Map<String, Object> isEggMap = getData0("isEgg", isEgg);
        datas.putAll(isEggMap);
        // 花粉
        String isDust = electronicMonitorTwoInfoVo.getIsDust();
        Map<String, Object> isDustMap = getData0("isDust", isDust);
        datas.putAll(isDustMap);
        // 酒精
        String isAlcohol = electronicMonitorTwoInfoVo.getIsAlcohol();
        Map<String, Object> isAlcoholMap = getData0("isAlcohol", isAlcohol);
        datas.putAll(isAlcoholMap);
        // 其它
        String isFoodOther = electronicMonitorTwoInfoVo.getIsFoodOther();
        Map<String, Object> isFoodOtherMap = getData0("isFoodOther", isFoodOther);
        datas.putAll(isFoodOtherMap);
        if (StringUtils.equals(isFoodOther, "0")) {
            datas.put("foodOther", electronicMonitorTwoInfoVo.getFoodOther());
        }
        // 注射期间是否服药
        String isTakePills = electronicMonitorTwoInfoVo.getIsTakePills();
        Map<String, Object> isTakePillsMap = getData0("isTakePills", isTakePills);
        datas.putAll(isTakePillsMap);
        if (StringUtils.equals(isTakePills, "1")) {
            datas.put("takePillsName", electronicMonitorTwoInfoVo.getTakePillsName());
        }
        // 不良反应/事件的结果
        String badResult = electronicMonitorTwoInfoVo.getBadResult();
        Map<String, Object> badResultMap = getData0("badResult", badResult);
        datas.putAll(badResultMap);
        if (StringUtils.equals(badResult, "4")) {
            datas.put("sequelaeManifestation", electronicMonitorTwoInfoVo.getSequelaeManifestation());
        }
        if (StringUtils.equals(badResult, "5")) {
            datas.put("dieReason", electronicMonitorTwoInfoVo.getDieReason());
            Date dieDate = electronicMonitorTwoInfoVo.getDieDate();
            if (ObjectUtil.isNotNull(dieDate)) {
                datas.put("year3", DateUtil.year(dieDate) - 2000);
                datas.put("month3", DateUtil.month(dieDate) + 1);
                datas.put("day3", DateUtil.dayOfMonth(dieDate));
                datas.put("hour3", DateUtil.hour(dieDate, true));
                datas.put("minute3", DateUtil.minute(dieDate));
            }
        }
        // 停药或减量后，反应/事件是否消失或减轻？
        String disappearedOrRelieve = electronicMonitorTwoInfoVo.getDisappearedOrRelieve();
        Map<String, Object> disappearedOrRelieveMap = getData0("disappearedOrRelieve", disappearedOrRelieve);
        datas.putAll(disappearedOrRelieveMap);
        // 再次使用可疑药品后是否再次出现同样反应/事件？
        String againShow = electronicMonitorTwoInfoVo.getAgainShow();
        Map<String, Object> againShowMap = getData0("againShow", againShow);
        datas.putAll(againShowMap);
        // 对原患疾病的影响
        String toOriginalAffect = electronicMonitorTwoInfoVo.getToOriginalAffect();
        Map<String, Object> toOriginalAffectMap = getData0("toOriginalAffect", toOriginalAffect);
        datas.putAll(toOriginalAffectMap);
        if (StringUtils.equals(toOriginalAffect, "3")) {
            datas.put("sequela", electronicMonitorTwoInfoVo.getSequela());
        }
        // 文字详细描述不良反应/事件发生发展过程
        Date happenTime = electronicMonitorTwoInfoVo.getHappenTime();
        if (ObjectUtil.isNotNull(happenTime)) {
            datas.put("year4", DateUtil.year(happenTime) - 2000);
            datas.put("month4", DateUtil.month(happenTime) + 1);
            datas.put("day4", DateUtil.dayOfMonth(happenTime));
            datas.put("hour4", DateUtil.hour(happenTime, true));
            datas.put("minute4", DateUtil.minute(happenTime));
        }
        datas.put("useMedicine", electronicMonitorTwoInfoVo.getUseMedicine());
        datas.put("useTime", electronicMonitorTwoInfoVo.getUseTime());
        datas.put("developSymptoms", electronicMonitorTwoInfoVo.getDevelopSymptoms());
        datas.put("checkSomething", electronicMonitorTwoInfoVo.getCheckSomething());
        datas.put("checkValue", electronicMonitorTwoInfoVo.getCheckValue());
        // 处理措施
        String handleStep = electronicMonitorTwoInfoVo.getHandleStep();
        Map<String, Object> handleStepMap = getData0("handleStep", handleStep);
        datas.putAll(handleStepMap);
        if (StringUtils.isNotBlank(handleStep)) {
            switch (handleStep) {
                case "0":
                    datas.put("otherMeasures", electronicMonitorTwoInfoVo.getOtherMeasures());
                    break;
                case "1":
                    datas.put("decrementOtherMeasures", electronicMonitorTwoInfoVo.getDecrementOtherMeasures());
                    break;
                case "2":
                    datas.put("noOtherMeasures", electronicMonitorTwoInfoVo.getNoOtherMeasures());
                    break;
                default:
                    break;
            }
        }
        // 再次使用情况描述
        String reuse = electronicMonitorTwoInfoVo.getReuse();
        Map<String, Object> reuseMap = getData0("reuse", reuse);
        datas.putAll(reuseMap);
        if (StringUtils.equals(reuse, "0")) {
            Date reuseUseTime = electronicMonitorTwoInfoVo.getReuseUseTime();
            if (ObjectUtil.isNotNull(reuseUseTime)) {
                datas.put("year5", DateUtil.year(reuseUseTime) - 2000);
                datas.put("month5", DateUtil.month(reuseUseTime) + 1);
                datas.put("day5", DateUtil.dayOfMonth(reuseUseTime));
                datas.put("hour5", DateUtil.hour(reuseUseTime, true));
                datas.put("minute5", DateUtil.minute(reuseUseTime));
            }
            datas.put("reuseUseMedicine", electronicMonitorTwoInfoVo.getReuseUseMedicine());
            datas.put("reuseDuration", electronicMonitorTwoInfoVo.getReuseDuration());
            datas.put("reuseDevelopSymptoms", electronicMonitorTwoInfoVo.getReuseDevelopSymptoms());
            datas.put("reuseHandle", electronicMonitorTwoInfoVo.getReuseHandle());
        }
        // 关联性评价
        // 报告人
        String relationReportPerson = electronicMonitorTwoInfoVo.getRelationReportPerson();
        Map<String, Object> relationReportPersonMap = getData0("relationReportPerson", relationReportPerson);
        datas.putAll(relationReportPersonMap);
        datas.put("relationInspectorSign", electronicMonitorTwoInfoVo.getRelationInspectorSign());
        // 报告单位
        String relationReportDept = electronicMonitorTwoInfoVo.getRelationReportDept();
        Map<String, Object> relationReportDeptMap = getData0("relationReportDept", relationReportDept);
        datas.putAll(relationReportDeptMap);
        datas.put("relationQualityControllerSign", electronicMonitorTwoInfoVo.getRelationQualityControllerSign());
        // 不良反应/事件记录表
        for (int i = 0; i < badRecordInfoVoList.size(); i++) {
            ElectronicBadRecordInfoVo electronicBadRecordInfoVo = badRecordInfoVoList.get(i);
            datas.put("goodsName" + i, electronicBadRecordInfoVo.getGoodsName());
            datas.put("authorizeNo" + i, electronicBadRecordInfoVo.getAuthorizeNo());
            datas.put("generalName" + i, electronicBadRecordInfoVo.getGeneralName());
            datas.put("productFactory" + i, electronicBadRecordInfoVo.getProductFactory());
            datas.put("batchNo" + i, electronicBadRecordInfoVo.getBatchNo());
            datas.put("usageAmount" + i, electronicBadRecordInfoVo.getUsageAmount());
            datas.put("beginEndDate" + i, electronicBadRecordInfoVo.getBeginEndDate());
            datas.put("usePillsReason" + i, electronicBadRecordInfoVo.getUsePillsReason());
        }
        // ◇不良反应/事件分析
        // ①用药与不良反应/事件的出现有无合理的时间关系？
        String relationTime = electronicMonitorTwoInfoVo.getRelationTime();
        Map<String, Object> relationTimeMap = getData0("relationTime", relationTime);
        datas.putAll(relationTimeMap);
        // ②反应是否符合该药已知的不良反应类型？
        String accordWithBadType = electronicMonitorTwoInfoVo.getAccordWithBadType();
        Map<String, Object> accordWithBadTypeMap = getData0("accordWithBadType", accordWithBadType);
        datas.putAll(accordWithBadTypeMap);
        // ③停药或减量后，反应/事件是否消失或减轻？
        String isDisappearedOrRelieve = electronicMonitorTwoInfoVo.getIsDisappearedOrRelieve();
        Map<String, Object> isDisappearedOrRelieveMap = getData0("isDisappearedOrRelieve", isDisappearedOrRelieve);
        datas.putAll(isDisappearedOrRelieveMap);
        // ④再次使用可疑药品后是否再次出现同样反应/事件？
        String isAgainShow = electronicMonitorTwoInfoVo.getIsAgainShow();
        Map<String, Object> isAgainShowMap = getData0("isAgainShow", isAgainShow);
        datas.putAll(isAgainShowMap);
        // ⑤反应/事件是否可用并用药的作用、患者病情的进展、其它治疗的影响来解释？
        String isEffectOther = electronicMonitorTwoInfoVo.getIsEffectOther();
        Map<String, Object> isEffectOtherMap = getData0("isEffectOther", isEffectOther);
        datas.putAll(isEffectOtherMap);
        // ◇严重药品不良反应/事件是指有下列情形之一者
        String severityBadShow = electronicMonitorTwoInfoVo.getSeverityBadShow();
        Map<String, Object> severityBadShowMap = getData1("severityBadShow", severityBadShow);
        datas.putAll(severityBadShowMap);
        // 监测员签名
        datas.put("inspectorSign", electronicMonitorTwoInfoVo.getInspectorSign());
        Date inspectorDate = electronicMonitorTwoInfoVo.getInspectorDate();
        if (ObjectUtil.isNotNull(inspectorDate)) {
            datas.put("year6", DateUtil.year(inspectorDate) - 2000);
            datas.put("month6", DateUtil.month(inspectorDate) + 1);
            datas.put("day6", DateUtil.dayOfMonth(inspectorDate));
        }
        // 质控员签名
        datas.put("qualityControllerSign", electronicMonitorTwoInfoVo.getQualityControllerSign());
        Date qualityControllerSignDate = electronicMonitorTwoInfoVo.getQualityControllerSignDate();
        if (ObjectUtil.isNotNull(qualityControllerSignDate)) {
            datas.put("year7", DateUtil.year(qualityControllerSignDate) - 2000);
            datas.put("month7", DateUtil.month(qualityControllerSignDate) + 1);
            datas.put("day7", DateUtil.dayOfMonth(qualityControllerSignDate));
        }
        return datas;
    }

    private void genCode(HttpServletResponse response, byte[] data, String zipName) throws IOException {
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("B表药品不良反应或事件报告", "UTF-8") + ".zip");
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(data, response.getOutputStream());
    }

    public Map<String, Object> getData0(String key, String value) {
        String[] list = {"0", "1", "2", "3", "4", "5"};
        Map<String, Object> datas = new HashMap<>();
        if (StringUtils.isEmpty(value)) {
            for (String str : list) {
                String key1 = key + str;
                datas.put(key1, new TextRenderData(getKey(153), new Style("Wingdings 2", 13)));
            }
            return datas;
        }
        for (String str : list) {
            String key1 = key + str;
            if (str.equals(value)) {
                datas.put(key1, new TextRenderData(getKey(85), new Style("Wingdings 2", 13)));
            } else {
                datas.put(key1, new TextRenderData(getKey(153), new Style("Wingdings 2", 13)));
            }
        }
        return datas;
    }

    public Map<String, Object> getData1(String key, String value) {
        String[] list = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"
            , "12", "13", "14", "15", "16", "17", "20", "21", "22", "23", "24", "25", "26", "27", "28"
            , "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43"
            , "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58"
            , "59", "60"};
        Map<String, Object> datas = new HashMap<>();
        if (StringUtils.isEmpty(value)) {
            for (String str : list) {
                String key1 = key + str;
                datas.put(key1, new TextRenderData(getKey(163), new Style("Wingdings 2", 13)));
            }
            return datas;
        }
        if (!value.contains(",")) {
            for (String str : list) {
                String key1 = key + str;
                if (str.equals(value)) {
                    datas.put(key1, new TextRenderData(getKey(83), new Style("Wingdings 2", 13)));
                } else {
                    datas.put(key1, new TextRenderData(getKey(163), new Style("Wingdings 2", 13)));
                }
            }
        } else {
            String[] split = value.split(",");
            for (String str : split) {
                String key1 = key + str;
                //if (str.equals(value)) {
                datas.put(key1, new TextRenderData(getKey(83), new Style("Wingdings 2", 13)));
                //}
            }
            for (String str : list) {
                String key1 = key + str;
                if (datas.get(key1) == null) {
                    datas.put(key1, new TextRenderData(getKey(163), new Style("Wingdings 2", 13)));
                }
            }

        }
        return datas;
    }

    public static String getKey(int num) {
        char ch = (char) num;
        return String.valueOf(ch);
    }

    /**
     * 不良反应/事件过程描述（包括表现、临床检验等）及处理情况-表现
     *
     * @return
     */
    private static Map<String, String> definedBadShow() {
        Map<String, String> badShowDefinedMap = new HashMap<>();
        badShowDefinedMap.put("皮疹", "1");
        badShowDefinedMap.put("斑丘疹", "2");
        badShowDefinedMap.put("剥脱性皮炎", "3");
        badShowDefinedMap.put("荨麻疹", "4");
        badShowDefinedMap.put("瘙痒", "5");
        badShowDefinedMap.put("血管神经性水肿", "6");
        badShowDefinedMap.put("多汗", "7");
        badShowDefinedMap.put("寒战", "8");
        badShowDefinedMap.put("头痛", "9");
        badShowDefinedMap.put("过敏样反应", "10");
        badShowDefinedMap.put("发热", "11");
        badShowDefinedMap.put("过敏性休克", "12");
        badShowDefinedMap.put("水肿", "13");
        badShowDefinedMap.put("眶周水肿", "14");
        badShowDefinedMap.put("喉水肿", "15");
        badShowDefinedMap.put("头晕", "16");
        badShowDefinedMap.put("抽搐", "17");
        badShowDefinedMap.put("局部麻木", "18");
        badShowDefinedMap.put("震颤", "19");
        badShowDefinedMap.put("失眠", "20");
        badShowDefinedMap.put("憋气", "21");
        badShowDefinedMap.put("口干", "22");
        badShowDefinedMap.put("腹痛", "23");
        badShowDefinedMap.put("恶心", "24");
        badShowDefinedMap.put("呕吐", "25");
        badShowDefinedMap.put("胃肠胀气", "26");
        badShowDefinedMap.put("腹泻", "27");
        badShowDefinedMap.put("非特异性食欲异常", "28");
        badShowDefinedMap.put("便秘", "29");
        badShowDefinedMap.put("大便变色", "30");
        badShowDefinedMap.put("哮喘", "31");
        badShowDefinedMap.put("呼吸困难", "32");
        badShowDefinedMap.put("咳嗽", "33");
        badShowDefinedMap.put("呼吸兴奋", "34");
        badShowDefinedMap.put("关节痛", "35");
        badShowDefinedMap.put("肌痛", "36");
        badShowDefinedMap.put("潮红", "37");
        badShowDefinedMap.put("心悸", "38");
        badShowDefinedMap.put("心脏停搏", "39");
        badShowDefinedMap.put("高血压", "40");
        badShowDefinedMap.put("低血压", "41");
        badShowDefinedMap.put("紫绀", "42");
        badShowDefinedMap.put("牙龈出血", "43");
        badShowDefinedMap.put("颅内出血", "44");
        badShowDefinedMap.put("静脉炎", "45");
        badShowDefinedMap.put("皮下出血", "46");
        badShowDefinedMap.put("血尿", "47");
        badShowDefinedMap.put("眼出血", "48");
        badShowDefinedMap.put("结膜出血", "49");
        badShowDefinedMap.put("紫癜", "50");
        badShowDefinedMap.put("排尿困难", "51");
        badShowDefinedMap.put("面部水肿", "52");
        badShowDefinedMap.put("低血钾", "53");
        badShowDefinedMap.put("肝功能异常", "54");
        badShowDefinedMap.put("其他", "55");
        return badShowDefinedMap;
    }
}
